package cn.sgw.common.tio.handlers;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.tio.core.Aio;
import org.tio.core.ChannelContext;

import cn.sgw.common.tio.server.BarrageHandlerIntf;
import cn.sgw.common.tio.server.BarragePacket;
import cn.sgw.common.util.BASE64Util;
import cn.sgw.common.util.SHA1Util;
import cn.sgw.common.tio.body.HandshakeBody;
import cn.sgw.common.tio.server.BarrageSessionContext;
import cn.sgw.common.tio.server.HttpRequestPacket;
import cn.sgw.common.tio.server.HttpResponsePacket;
import cn.sgw.common.tio.server.HttpResponseStatus;
import cn.sgw.common.tio.server.Type;

public class HandshakeReqHandler implements BarrageHandlerIntf<HandshakeBody> {

    private BarragePacket handshakeRespPacket = new BarragePacket(Type.COMMAND_HANDSHAKE_RESP);

    @Override
    public Object handler(
            BarragePacket packet,
            String body,
            ChannelContext<BarrageSessionContext, BarragePacket, Object> channelContext)
            throws Exception {
        BarrageSessionContext barrageSessionContext = channelContext.getSessionContext();
        barrageSessionContext.setHandshaked(true);

        boolean isWebsocket = barrageSessionContext.isWebsocket();
        if (isWebsocket) {
            HttpRequestPacket httpRequestPacket = (HttpRequestPacket) packet;
            HttpResponsePacket httpResponsePacket = updateWebSocketProtocol(httpRequestPacket);
            if (httpResponsePacket != null) {
                httpResponsePacket.setType(Type.COMMAND_HANDSHAKE_RESP);
                Aio.send(channelContext, httpResponsePacket);
            } else {
                Aio.remove(channelContext, "不是websocket协议");
            }
        } else {
            Aio.send(channelContext, handshakeRespPacket);
        }
        return null;
    }

    public HttpResponsePacket updateWebSocketProtocol(HttpRequestPacket httpRequestPacket) {
        Map<String, String> headers = httpRequestPacket.getHeaders();

        String Sec_WebSocket_Key = headers.get("Sec-WebSocket-Key");

        if (StringUtils.isNotBlank(Sec_WebSocket_Key)) {
            String Sec_WebSocket_Key_Magic = Sec_WebSocket_Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
            byte[] key_array = SHA1Util.SHA1(Sec_WebSocket_Key_Magic);
            String acceptKey = BASE64Util.byteArrayToBase64(key_array);
            HttpResponsePacket httpResponsePacket = new HttpResponsePacket();

            HttpResponseStatus httpResponseStatus = HttpResponseStatus.C101;
            httpResponsePacket.setHttpResponseStatus(httpResponseStatus);

            Map<String, String> respHeaders = new HashMap<>();
            respHeaders.put("Connection", "Upgrade");
            respHeaders.put("Upgrade", "WebSocket");
            respHeaders.put("Sec-WebSocket-Accept", acceptKey);
            httpResponsePacket.setHeaders(respHeaders);
            return httpResponsePacket;
        }
        return null;
    }

}
